#ifndef FILESYSTEMHANDLER_H
#define FILESYSTEMHANDLER_H

#include "systemCallHandler.h"
#include <QFile>
#include <QTextStream>
#include <QDir>
#include <QFileInfo>
#include <QMap>
#include <map>
#include <memory>

/**
 * @brief 文件句柄结构体
 * 封装文件操作的相关信息
 */
struct FileHandle {
    int handleId;                           // 文件句柄ID
    std::unique_ptr<QFile> file;           // 文件对象智能指针
    std::unique_ptr<QTextStream> stream;   // 文本流智能指针
    QString fileName;                       // 文件名
    int accessMode;                         // 访问模式（0=只读, 1=只写, 2=读写）
    qint64 position;                        // 当前文件位置
    bool isValid;                           // 句柄是否有效
    
    FileHandle() : handleId(-1), position(0), isValid(false) {}
};

/**
 * @brief 文件系统处理器类
 * 
 * 处理所有文件相关的系统调用，包括文件的打开、关闭、读写、删除等操作。
 * 支持的中断号范围：0x10-0x1F
 */
class FileSystemHandler : public SystemCallHandler
{
    Q_OBJECT

public:
    explicit FileSystemHandler(QObject *parent = nullptr);
    ~FileSystemHandler() override;

    // 重写基类虚函数
    SystemCallResult handleInterrupt(int interruptNumber, CpuSimulator* cpu) override;
    QPair<int, int> getSupportedInterruptRange() const override;
    QString getDescription() const override;
    void reset() override;

private:
    /**
     * @brief INT 0x10 - 打开文件
     * 参数：AX=文件名地址, BX=访问模式
     * 返回：AX=文件句柄（-1表示失败）
     */
    SystemCallResult handleOpenFile(CpuSimulator* cpu);

    /**
     * @brief INT 0x11 - 关闭文件
     * 参数：AX=文件句柄
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleCloseFile(CpuSimulator* cpu);

    /**
     * @brief INT 0x12 - 读取文件
     * 参数：AX=文件句柄, BX=缓冲区地址, CX=读取字节数
     * 返回：AX=实际读取字节数
     */
    SystemCallResult handleReadFile(CpuSimulator* cpu);

    /**
     * @brief INT 0x13 - 写入文件
     * 参数：AX=文件句柄, BX=缓冲区地址, CX=写入字节数
     * 返回：AX=实际写入字节数
     */
    SystemCallResult handleWriteFile(CpuSimulator* cpu);

    /**
     * @brief INT 0x14 - 文件定位
     * 参数：AX=文件句柄, BX=新位置
     * 返回：AX=新位置
     */
    SystemCallResult handleSeekFile(CpuSimulator* cpu);

    /**
     * @brief INT 0x15 - 获取文件大小
     * 参数：AX=文件句柄
     * 返回：AX=文件大小
     */
    SystemCallResult handleGetFileSize(CpuSimulator* cpu);

    /**
     * @brief INT 0x16 - 删除文件
     * 参数：AX=文件名地址
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleDeleteFile(CpuSimulator* cpu);

    /**
     * @brief INT 0x17 - 重命名文件
     * 参数：AX=旧文件名地址, BX=新文件名地址
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleRenameFile(CpuSimulator* cpu);

    /**
     * @brief INT 0x18 - 检查文件是否存在
     * 参数：AX=文件名地址
     * 返回：AX=存在标志（1=存在, 0=不存在）
     */
    SystemCallResult handleFileExists(CpuSimulator* cpu);

    /**
     * @brief INT 0x19 - 创建目录
     * 参数：AX=目录名地址
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleCreateDirectory(CpuSimulator* cpu);

    /**
     * @brief INT 0x1A - 删除目录
     * 参数：AX=目录名地址
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleRemoveDirectory(CpuSimulator* cpu);

    /**
     * @brief INT 0x1B - 获取当前工作目录
     * 参数：AX=缓冲区地址, BX=缓冲区大小
     * 返回：AX=路径长度
     */
    SystemCallResult handleGetCurrentDirectory(CpuSimulator* cpu);

    /**
     * @brief INT 0x1C - 设置当前工作目录
     * 参数：AX=目录路径地址
     * 返回：AX=状态码（0=成功）
     */
    SystemCallResult handleSetCurrentDirectory(CpuSimulator* cpu);

    // 辅助方法
    
    /**
     * @brief 从内存中读取以空字符结尾的字符串
     * @param cpu CPU模拟器指针
     * @param address 字符串在内存中的起始地址
     * @return QString 读取的字符串
     */
    QString readStringFromMemory(CpuSimulator* cpu, int address);

    /**
     * @brief 向内存中写入字符串
     * @param cpu CPU模拟器指针
     * @param address 目标内存地址
     * @param str 要写入的字符串
     * @return int 实际写入的字节数
     */
    int writeStringToMemory(CpuSimulator* cpu, int address, const QString& str);

    /**
     * @brief 从内存中读取数据
     * @param cpu CPU模拟器指针
     * @param address 起始地址
     * @param size 数据大小
     * @return QByteArray 读取的数据
     */
    QByteArray readDataFromMemory(CpuSimulator* cpu, int address, int size);

    /**
     * @brief 向内存中写入数据
     * @param cpu CPU模拟器指针
     * @param address 目标地址
     * @param data 要写入的数据
     * @return int 实际写入的字节数
     */
    int writeDataToMemory(CpuSimulator* cpu, int address, const QByteArray& data);

    /**
     * @brief 分配新的文件句柄
     * @return int 新的文件句柄ID（-1表示分配失败）
     */
    int allocateFileHandle();

    /**
     * @brief 释放文件句柄
     * @param handleId 要释放的句柄ID
     */
    void deallocateFileHandle(int handleId);

    /**
     * @brief 获取文件句柄
     * @param handleId 句柄ID
     * @return FileHandle* 文件句柄指针（nullptr表示无效）
     */
    FileHandle* getFileHandle(int handleId);

    /**
     * @brief 验证文件访问权限
     * @param handle 文件句柄
     * @param requireRead 是否需要读权限
     * @param requireWrite 是否需要写权限
     * @return bool 权限验证结果
     */
    bool validateFileAccess(const FileHandle* handle, bool requireRead, bool requireWrite);

private:
    std::map<int, std::unique_ptr<FileHandle>> fileHandles; // 文件句柄映射表
    int nextHandleId;                                        // 下一个可用的句柄ID
    QString currentWorkingDirectory;                         // 当前工作目录
    
    static const int MAX_FILE_HANDLES = 256;                 // 最大文件句柄数
    static const int MAX_FILENAME_LENGTH = 1024;             // 最大文件名长度
    static const int MAX_BUFFER_SIZE = 65536;                // 最大缓冲区大小
};

#endif // FILESYSTEMHANDLER_H 